﻿using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using LdtJudge.DataEngine.Model.XMLConfigModel.SameNodeConfigModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LdtDataEngin.ModuleDetail.OptimizationModule.StageOptimization
{
    /// <summary>
    /// 证据要素实体比对
    /// </summary>
    public class EvidenceUnionDataModel
    {
        /// <summary>
        /// 对证据实体进行比对,将第一份实体数据合并到第二份实体数据
        /// </summary>
        /// <param name="dataModelListOne">第一份实体(上阶段)</param>
        /// <param name="oneParentID">第一份实体父级ID</param>
        /// <param name="dataModelListTwo">第二份实体(传入阶段)</param>
        /// <param name="twoParentID">第二份实体父级ID</param>
        /// <param name="xmlConfigModels">相同节点配置实体</param>
        /// <param name="nodeHandleType">比对方式</param>
        public void MergeNode(List<DataModel> dataModelListOne,string oneParentID,List<DataModel> dataModelListTwo, string twoParentID,List<SameNodeXml> xmlConfigModels, string nodeHandleType)
        {
            foreach (DataModel dataModelone in dataModelListOne.Where(x=>x.ParentId==oneParentID))
            {
                string xmlpath = dataModelone.XmlPath;
                string configxmlpath = xmlpath.Replace("详情/证据相关信息/证据/详情/证据内容/详情","").Replace("证据要素","");
                if (!string.IsNullOrEmpty(configxmlpath))
                {
                    string[] paths = configxmlpath.Split(@"/", StringSplitOptions.RemoveEmptyEntries);
                    if (paths.Length>0)
                        configxmlpath = string.Join(@"/", paths).TrimStart('/');
                    else
                        configxmlpath = string.Empty;
                }
                SameNodeXml sameNodeXml = xmlConfigModels?.FirstOrDefault(a => a.XmlPath == configxmlpath);
                bool isSameData = false;
                //第一份实体的同节点DataModel数据
                DataModel sameOneData = null;
                //第二份实体的同节点DataModel数据
                DataModel sameTwoData = null;
                //获取第二份实体(传入阶段)参与合并的数据集合
                var dataModelTwos = dataModelListTwo.Where(x=>x.ParentId==twoParentID).ToList();
                if (dataModelTwos.Any(a => a.XmlPath == xmlpath || a.XmlPath == configxmlpath))
                {
                    List<DataModel> dataModelsTwo = dataModelTwos.Where(a => a.XmlPath == dataModelone.XmlPath || a.XmlPath == configxmlpath).ToList();
                    foreach (DataModel dataTwo in dataModelsTwo)
                    {
                        //比对DataModel数据是否为相同节点数据
                        bool dataCompare = IsSameNode(dataModelone, dataTwo, sameNodeXml, nodeHandleType);
                        if (dataCompare)
                        {
                            isSameData = true;
                            sameOneData = dataModelone;
                            sameTwoData = dataTwo;
                        }
                    }
                    if(isSameData)
                    {
                        //合并相同数据节点
                        MergeData(dataModelListOne, sameOneData, dataModelListTwo, sameTwoData, xmlConfigModels,configxmlpath,nodeHandleType);
                        MergeNode(dataModelListOne, sameOneData.ID, dataModelListTwo, sameTwoData.ID, xmlConfigModels, nodeHandleType);
                    }
                    else if(isSameData == false && sameNodeXml != null)
                    {
                        //不存在相同节点数据，将第一份实体(上阶段)数据集合添加到第二份实体数据集合中
                        dataModelone.ParentId = twoParentID;
                        var subDataModels = SubordinateDataModelList(dataModelListOne, dataModelone);
                        dataModelListTwo.AddRange(subDataModels);
                    }
                }
                else
                {
                    dataModelone.ParentId = twoParentID;
                    var subDataModels = SubordinateDataModelList(dataModelListOne, dataModelone);
                    dataModelListTwo.AddRange(subDataModels);
                }
            }
        }

        // <summary>
        /// 合并DataModel数据
        /// </summary>
        /// <param name="dataModelListOne">第一份实体集合(上阶段)</param>
        /// <param name="oneData">第一份实体</param>
        /// <param name="dataModelListTwo">第二份实体集合(传入阶段)</param>
        /// <param name="twoData">第二份实体</param>
        /// <param name="xmlConfigModels">相同节点配置实体</param>
        /// <param name="configXmlPath">配置实体xml路径</param>
        /// <param name="nodeHandleType">比对方式</param>
        public void MergeData(List<DataModel> dataModelListOne,DataModel oneData, List<DataModel> dataModelListTwo, DataModel twoData,List<SameNodeXml> xmlConfigModels, string configXmlPath, string nodeHandleType)
        {
            SameNodeXml sameNodeXml = xmlConfigModels?.FirstOrDefault(a => a.XmlPath == configXmlPath);
            if (sameNodeXml!=null)
            {
                var evidHandle = sameNodeXml.HandleTypes.FirstOrDefault(x => x.Code.Contains("c"));
                if (evidHandle?.IsCover != "1")
                {
                    foreach (AttributeInfo attributeInfo in oneData.AttributesList)
                    {
                        if (attributeInfo.Name.ToLower() != "id")
                        {
                            var attinfoTow = twoData.AttributesList.FirstOrDefault(a => a.Name == attributeInfo.Name);
                            if (attinfoTow == null)
                            {
                                twoData.AttributesList.Add(attributeInfo);
                            }
                        }
                    }
                }
            }
            if (dataModelListOne.Any(x => x.ParentId == oneData.ID))
            {
                MergeNode(dataModelListOne, oneData.ID, dataModelListTwo, twoData.ID, xmlConfigModels,nodeHandleType);
            }
        }

        /// <summary>
        /// 进行数据比对
        /// </summary>
        /// <param name="dataModelOne">第一个数据源</param>
        /// <param name="dataModelTowe">第二个数据源</param>
        /// <param name="xmlConfigModel">同节点配置</param>
        /// <param name="nodeHandleType">比对方式</param>
        /// <returns></returns>
        public bool IsSameNode(DataModel dataModelOne, DataModel dataModelTowe, SameNodeXml xmlConfigModel, string nodeHandleType)
        {
            bool issameNode = true;
            if(xmlConfigModel!=null)
            {
                //判断当前的业务类型是否在配置中存在
                var handletype = xmlConfigModel.HandleTypes.FirstOrDefault(m => m.Code.Contains(nodeHandleType.ToString()));
                if (handletype != null)
                {
                    if (handletype.CurrentNote != null && handletype.CurrentNote.Count > 0)
                    {//进行判定当前节点的标识是否为空
                        List<string> notlist = handletype.CurrentNote.Select(a => a.Name).ToList();
                        issameNode = DataModelEquals(dataModelOne, dataModelTowe, notlist);
                    }
                }
            }
            return issameNode;
        }

        /// <summary>
        /// 两个数据进行对比是否为相同的节点
        /// </summary>
        /// <param name="dataModelOne">第一个数据</param>
        /// <param name="dataModelTowe"></param>
        /// <param name="noteList"></param>
        /// <returns></returns>
        protected bool DataModelEquals(DataModel dataModelOne, DataModel dataModelTowe, List<string> noteList)
        {
            if(noteList!=null && noteList.Any())
            {
                bool issame = true;
                foreach (string note in noteList)
                {
                    AttributeInfo attributeone = dataModelOne.AttributesList.FirstOrDefault(a => a.Name == note && a.sourceList.FirstOrDefault(b => b.IsCheck == "1") != null);
                    AttributeInfo attributetow = dataModelTowe.AttributesList.FirstOrDefault(a => a.Name == note && a.sourceList.FirstOrDefault(b => b.IsCheck == "1") != null);
                    if (attributeone != null && attributetow != null)
                    {
                        var attrValueOne = attributeone.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                        var attrValueTwo = attributetow.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                        if (attrValueOne != attrValueTwo)
                        {
                            issame = false;
                        }
                    }
                }
                return issame;
            }
            else
            {
                //如果标识为空，则进行的当前节点的全属性对比
                if(dataModelOne.AttributesList.Count==dataModelOne.AttributesList.Count)
                {
                    bool issame = true;
                    foreach (var arrtItem in dataModelOne.AttributesList)
                    {
                        AttributeInfo attributetow = dataModelTowe.AttributesList.FirstOrDefault(a => a.Name == arrtItem.Name && a.sourceList.FirstOrDefault(b => b.IsCheck == "1") != null);
                        if(attributetow!=null)
                        {
                            var attrValueOne = arrtItem.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                            var attrValueTwo = attributetow.sourceList.FirstOrDefault(a => a.IsCheck == "1").SaveValue;
                            if (attrValueOne != attrValueTwo)
                            {
                                issame = false;
                                break;
                            }
                        }
                    }
                    return issame;
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 获取下级所有子节点
        /// </summary>
        /// <param name="dataModelList">数据源集合</param>
        /// <param name="dataModel">当前数据</param>
        /// <returns></returns>
        protected List<DataModel> SubordinateDataModelList(List<DataModel> dataModelList, DataModel dataModel)
        {
            List<DataModel> dataList = new List<DataModel>();
            dataList.Add(dataModel);
            List<DataModel> datasModels = dataModelList.Where(a => a.ParentId == dataModel.ID && a.ID != dataModel.ID).ToList();
            foreach (DataModel model in datasModels)
            {
                List<DataModel> dataModelValueList = SubordinateDataModelList(dataModelList, model);
                dataList.AddRange(dataModelValueList);
            }
            return dataList;
        }








    }
}
